package com.example.service.impl;

import com.example.vo.UserDetail;
import com.example.vo.UserVo;
import com.example.entity.User;
import com.example.repository.BaseRepository;
import com.example.repository.RoleRepository;
import com.example.repository.UserRepository;
import com.example.service.UserService;
import com.example.config.security.JwtTokenUtil;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

@Service
public class UserServiceImpl extends BaseReactiveServiceImpl<User> implements UserService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    UserRepository userRepository;

    @Autowired
    RoleRepository roleRepository;

    @Autowired
    Mapper mapper;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Override
    protected BaseRepository<User> getRepository() {
        return userRepository;
    }

    @Override
    public Mono<UserVo> login(Authentication authentication) {
        User user = userRepository.findByUsername(authentication.getName());
        UserDetail userDetail = new UserDetail(user.getId(), user.getUsername(), user.getPassword(), user.getRoles());
        UserVo userVo = mapper.map(user, UserVo.class);
        //密码不返回
        userVo.setPassword(null);
        userVo.setAccess_token(jwtTokenUtil.generateAccessToken(userDetail));
        return Mono.fromCallable(() -> userVo).subscribeOn(scheduler);
    }

    @Override
    public Mono<User> findByUsername(String username) {
        User user = userRepository.findByUsername(username);
        if (null == user) {
            return null;
        }
        return async(() -> userRepository.findByUsername(username));
    }

    @Override
    public Mono<Boolean> exit(String username) {
        boolean exit = true;
        Mono<User> user = findByUsername(username);
        if (Mono.empty().equals(user)) {
            exit = false;
        }
        return Mono.just(exit);
    }

    @Override
    public Mono<Void> create(UserVo userVo) {
        Mono<User> existing = findByUsername(userVo.getUsername());
        if (null == existing) {
            String hashPassword = passwordEncoder.encode(userVo.getPassword());
            User user = mapper.map(userVo, User.class);
            user.setPassword(hashPassword);
            userRepository.save(user);
        }
        return Mono.empty();
    }
}
